#include "QtRendersetting.h"



BusiCoord::BusiCoord(QRect& rect, BarSeries* pBarSer, BarData* pData)
{
	m_pBusiRect = new QRect(LeftMargin, 0, rect.width() - LeftMargin - RightMargin, rect.height());

	
	{
		m_zoomsize = 6;
		m_zoomset = new ZoomSeetings[m_zoomsize];
		m_zoomindex = m_zoomsize / 2;

		double factor = 0.8;

		m_zoomset[0].distance = 5;
		m_zoomset[0].barwidth = m_zoomset[0].distance * factor;
		m_zoomset[1].distance = 10;
		m_zoomset[1].barwidth = m_zoomset[1].distance * factor;
		m_zoomset[2].distance = 20;
		m_zoomset[2].barwidth = m_zoomset[2].distance * factor;
		m_zoomset[3].distance = 30;
		m_zoomset[3].barwidth = m_zoomset[3].distance * factor;
		m_zoomset[4].distance = 40;
		m_zoomset[4].barwidth = m_zoomset[4].distance * factor;
		m_zoomset[5].distance = 50;
		m_zoomset[5].barwidth = m_zoomset[5].distance * factor;
	}
	
	m_pBarSer = pBarSer;
	
	
	m_pData = new BarData;
	if (m_pData)
	{
		memcpy(m_pData, pData, sizeof(BarData));
	}
	else
		m_pData = NULL;


	m_bcursorstate = false;



	SetBusiCoordIndex(-1);


}

BusiCoord::~BusiCoord()
{
	if (m_zoomset)
		delete []m_zoomset;

	if (m_pData)
		delete m_pData;
	
}

void BusiCoord::SetBusiCoordIndex(int paraMaxIndex)
{

	m_bValid = false;

	if (SetBusiCoordIndexCore(paraMaxIndex))
		m_bValid = true;
}

bool BusiCoord::SetBusiCoordIndexCore(int paraMaxIndex)
{
	//Get contain num in m_rect
	int num = m_pBusiRect->width() / m_zoomset[m_zoomindex].distance - MarginBarnum;
	if (num <= 0 || NULL == m_pData || NULL == m_pBarSer)
		return false;


	{
		//set m_minXIndex = m_maxXIndex
		if (-1 == paraMaxIndex)
			m_maxXIndex = m_pData->index;
		else
			m_maxXIndex = paraMaxIndex;

		m_minXIndex = m_maxXIndex - num + 1;//default rule is that from maxXIndex find back to minXIndex

		if (m_minXIndex < 0)////if minXIndex is less than zero, then find front to maxXIndex
		{
			int tmp = -m_minXIndex;

			m_maxXIndex += tmp;

			if (m_maxXIndex > m_pData->index)
			{
				m_maxXIndex = m_pData->index;
			}


			m_minXIndex = 0;
		}

		//printf("[SetBusiCoord] m_minXIndex:%d, m_maxXIndex:%d\n", m_minXIndex, m_maxXIndex);
	}

	return true;


}




bool BusiCoord::SetScroll(int dx)
{
	if (m_bValid)
	{
		if (-1 == dx && m_minXIndex > 0)
		{
			m_minXIndex += dx;
			m_maxXIndex += dx;

			return true;
		}
		else if (1 == dx && m_maxXIndex < m_pData->index)
		{
			m_minXIndex += dx;
			m_maxXIndex += dx;

			return true;
		}

	}

	return false;

}



bool BusiCoord::SetBarData(BarData* pData)
{
	
	if (m_bValid)
	{

		int minXIndex; int maxXIndex; 
		BusiCoordIndex(minXIndex, maxXIndex);//because there is m_bValid judgement before so no need return judegment for this return

		if (maxXIndex == m_pData->index)
		{
			memcpy(m_pData, pData, sizeof(BarData));// if m_pData is NULL, m_bValid should be false, so no need judegment

			SetBusiCoordIndex(-1);

			return true;
		}
		else
		{
			memcpy(m_pData, pData, sizeof(BarData));

			return false;
		}


	}


	return false;

}

bool BusiCoord::GetBarData(int index, BarData* &pData)
{
	if (m_bValid)
	{
		if (index >= m_minXIndex && index < m_pData->index)
		{
			pData = m_pBarSer->GetBarData(index);

			return true;
		}
		else if (index == m_pData->index)
		{
			pData = m_pData;

			return true;
		}
		else
			return false;
		

	}

	return false;
}


bool BusiCoord::SetZoom(zoomset option)
{
	if (m_bValid)
	{
		bool bupdate = false;

		if (zoomin == option)
		{
			if (m_zoomindex < m_zoomsize - 1)
			{
				m_zoomindex++;

				bupdate = true;
			}

		}
		else if (zoomout == option)
		{
			if (m_zoomindex > 0)
			{
				m_zoomindex--;

				bupdate = true;
			}
		}


		if (bupdate)
		{

			resizeORzoom();

			return true;
		}

		return false;
	}
	

	return false;

}

void BusiCoord::SetBusiRect(QRect& rect)
{

	m_pBusiRect->setRect(LeftMargin, 0, rect.width() - LeftMargin - RightMargin, rect.height());


	resizeORzoom();
}


bool BusiCoord::BusiCoordIndex(int& minXIndex, int& maxXIndex)
{
	if (m_bValid)
	{
		minXIndex = m_minXIndex;

		maxXIndex = m_maxXIndex;

		return true;
	}

	return false;

}



//resize Or zoom operation may cause  shown bar(invalid m_rect or bigger bar size)
//so set last element to display (set -1 pamameter) 
void BusiCoord::resizeORzoom()
{
	int destIndex = -1;

	//for not m_rect not big enough set maxXIndex to size() - 1;
	int minXIndex; int maxXIndex; 
	if (BusiCoordIndex(minXIndex, maxXIndex))
	{
		destIndex = maxXIndex; 

	}
		


	SetBusiCoordIndex(destIndex);




}


bool BusiCoord::IsValidCurosr(QPoint& point)
{

	if (m_pBusiRect->contains(point)) 
	{
		
		SetCursorORUncursor(true);

		SetCursorIndex(point);


		return true;
	}
	else
	{
		SetCursorORUncursor(false);

		return false;
	}

	
}


void BusiCoord::SetCursorIndex(QPoint& point)
{
	m_cursorIndex = (point.x() - m_pBusiRect->left()) / m_zoomset[m_zoomindex].distance + m_minXIndex;

	if (m_cursorIndex > m_maxXIndex)
	{
		m_cursorIndex = m_maxXIndex;
	}
	
}


int BusiCoord::GetCursorIndex()
{
	if (m_bcursorstate)
	{
		return m_cursorIndex;
	} 
	else
	{
		return (int)m_pData->index;
	}
	

}

void BusiCoord::SetCursorORUncursor(bool bvalue)
{
	m_bcursorstate = bvalue;

}